﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

//Fixed width integer types (since C++11)
#include <cstdint>

namespace gnuf {

/**********************ICON************************/
    // icon size
    enum class EIconSize : std::uint16_t
    {
        // special num for casting to integer in an easy way
        e4x4 = 4,
        e8x8 = 8,
        e12x12 = 12,
        e16x16 = 16,
        e24x24 = 24,
        e32x32 = 32,
        e48x48 = 48,
        e64x64 = 64,
        e96x96 = 96,
        e128x128 = 128,
        e256x256 = 256,

        // customize
        eCustomize = 0xffff
    };

    // icon status
    enum class EIconStatus : std::uint8_t
    {
        eDefault,
        eDisabled,
        eHovered,
        eSelected
    };

/************************Theme***********************/
    enum class ETheme : std::uint8_t
    {
        eUnknown = 0xff, //-1
        eLight = 0,
        eDark,

        // add theme above here
        eThemeNumber
    };

/**********************COLOR CODE***********************/
    enum class ColorCode : std::uint32_t
    {
        Text01, Text02, Text03,
        Button01, Button02,
        Label01, Label02,
        Panel01, Panel02, Panel03, PanelM,
        Input01, Input02,
        Line01, Line02, Line03,
        TopT2, TopT1, TopB2, TopB1, TopTag1,
        B01, B02, B03, B04,
        M101, M102, M201, M202, M301, M302,
        Transparent, SliderG, SliderH, SliderHM, 
        Line04,
        EditMode01, // face color of disabled elements in editing mode
        Invalid
    };

/**********************CHECK***********************/
    // check box or radio button
    enum class CheckStatus : std::uint8_t
    {
        UnChecked,
        PartiallyChecked, // only in check box
        Checked
    };

    // one to one correspondence with enum CheckStatus
    // separator '/' can cross platform at least in UNIX, LINUX and WINDOWS. dont use '\\'(ms-windows)
    // note: MacOS is base on UNIX(BSD),  cored by Darwin
    constexpr wchar_t* Checked = L"CheckStatus/Checked";
    constexpr wchar_t* PartiallyChecked = L"CheckStatus/PartiallyChecked";
    constexpr wchar_t* UnChecked = L"CheckStatus/UnChecked";

/************************LAYOUT***********************/
    enum class Direction : std::uint8_t
    {
        Horizontal,
        Vertical
    };

    typedef struct Region
    {
        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;

        // initialize for syntactic sugar 'initialize_list' (alias: expression {} )
        Region(int l, int t, int r, int b)
            : left(l), top(t), right(r), bottom(b)
        {}

        // intialize for all
        Region(int space)
            : left(space), top(space), right(space), bottom(space)
        {}

        // support the copy and assignment
        Region(const Region& other)
            : left(other.left), top(other.top), right(other.right), bottom(other.bottom)
        {}

        Region& operator=(const Region& other)
        {
            if (this == &other) return *this;
            this->left = other.left;
            this->right = other.right;
            this->top = other.top;
            this->bottom = other.bottom;
            return *this;
        }

        // support for equation
        bool operator==(const Region& other) const
        {
            return (this->left == other.left)
                && (this->right == other.right)
                && (this->top == other.top)
                && (this->bottom == other.bottom);
        }

        // support for associated container
        bool operator<(const Region& other) const 
        {
            if (this->left < other.left) return true;
            if (this->left > other.left) return false;
            if (this->top < other.top) return true;
            if (this->top > other.top) return false;
            if (this->right < other.right) return true;
            if (this->right > other.right) return false;
            if (this->bottom < other.bottom) return true;
            if (this->bottom > other.bottom) return false;
            return false;
        }

        int x()         const { return this->left; }
        int y()         const { return this->top; }
        int width()     const { return (this->right - this->left); }
        int height()    const { return (this->bottom - this->top); }
        bool isValid()  const { return (this->width() > 0 && this->height() > 0); }
        void reset() { this->left = this->right = this->right = this->bottom = 0; }

        // default constructor/disconstructor
        Region() {}
        ~Region() {}
    } Margin, Padding, Rect, Geometry;

    enum EPlacement
    {
        eAtTheTop = 1 << 0,
        eAtTheRight = 1 << 1,
        eAtTheBottom = 1 << 2,
        eAtTheLeft = 1 << 3,
        eAtTheTopAndLeft = 1 << 4,
        eAtTheTopAndRight = 1 << 5,
        eAtTheBottomAndRight = 1 << 6,
        eAtTheBottomAndLeft = 1 << 7
    };

    enum class EBadgeType : std::uint8_t
    {
        eTriangle,
        eSolidCircle,
        eText
    };

    enum EAlignment // int
    {
        AlignLeft = 0x0001,
        AlignLeading = AlignLeft,
        AlignRight = 0x0002,
        AlignTrailing = AlignRight,
        AlignHCenter = 0x0004,
        AlignJustify = 0x0008,
        AlignAbsolute = 0x0010,
        AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute,

        AlignTop = 0x0020,
        AlignBottom = 0x0040,
        AlignVCenter = 0x0080,
        AlignBaseline = 0x0100,
        // Note that 0x100 will clash with Qt::TextSingleLine = 0x100 due to what the comment above
        // this enum declaration states. However, since Qt::AlignBaseline is only used by layouts,
        // it doesn't make sense to pass Qt::AlignBaseline to QPainter::drawText(), so there
        // shouldn't really be any ambiguity between the two overlapping enum values.
        AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter | AlignBaseline,

        AlignCenter = AlignVCenter | AlignHCenter
    };

    constexpr int GrowFlag = 1;
    constexpr int ExpandFlag = 2;
    constexpr int ShrinkFlag = 4;
    constexpr int IgnoreFlag = 8;

    enum class ESizePolicy
    {
        Fixed = 0,
        Minimum = GrowFlag,
        Maximum = ShrinkFlag,
        Preferred = GrowFlag | ShrinkFlag,
        MinimumExpanding = GrowFlag | ExpandFlag,
        Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
        Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
    };

    enum class ELayoutSizeConstraint
    {
        SetDefaultConstraint,
        SetNoConstraint,
        SetMinimumSize,
        SetFixedSize,
        SetMaximumSize,
        SetMinAndMaxSize
    };

    /// \brief 按钮的展示样式
    enum class EButtonDisplayStyle
    {
        eTextIcon = 1, ///< 文字和图标
        eIconOnly, ///< 只展示图标
        eTextOnly, ///< 只展示文字
        eDefault ///< 不改动现有设置 
    };

    enum class EMatrixSize : std::uint8_t
    {
        e2x2 = 2,
        e3x3 = 3
    };

    enum class EIcon : std::uint8_t
    {
        eSuccess,
        eInfo,
        eWarningInfo,
        eLowWarning,
        eWarning,
        eHighWarning,
        eError
    };
}
